package io.renren.common.utils;

import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;
import org.lionsoul.ip2region.DataBlock;
import org.lionsoul.ip2region.DbConfig;
import org.lionsoul.ip2region.DbMakerConfigException;
import org.lionsoul.ip2region.DbSearcher;
import org.springframework.core.io.ClassPathResource;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;

public class IPUtil {
    /**
     * 获取IP地址
     * @param request
     * @return
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        if ("0:0:0:0:0:0:0:1".equals(ip)) {
            ip = "127.0.0.1";
        }
        if (ip.split(",").length > 1) {
            ip = ip.split(",")[0];
        }
        return ip;
    }

    /**
     * 根据IP地址获取城市
     *
     * @param ip
     * @return
     */
    public static String getCityInfo(String ip) throws Exception {
        //读取jar包内的配置文件信息
        DbSearcher searcher = null;
        Method method = null;
        InputStream inputStream = null;
        try {
            ClassPathResource resource = new ClassPathResource("/ip2region.db");
            inputStream = resource.getInputStream();
            byte[] dbBinStr = IoUtil.readBytes(inputStream);
            DbConfig config = new DbConfig();
            searcher = new DbSearcher(config, dbBinStr);
            // 查询算法memory，采用二进制方式初始化DBSearcher需要使用MEMORY_ALGORITYM，
            //否则会抛出null。
            method = searcher.getClass().getMethod("memorySearch", String.class);
        } catch (IOException | DbMakerConfigException | IORuntimeException | NoSuchMethodException | SecurityException e) {
//            log.error(e.getMessage());
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
        }
        return ((DataBlock) method.invoke(searcher, ip)).getRegion();
    }

    public static void main(String[] args) {
        //百度ip地址
        String baidiIp = "110.242.68.3";
        //csdn IP地址
        String csdnIp = "39.106.226.142";
        String cityInfo = null;
        try {
            cityInfo = getCityInfo(csdnIp);
        } catch (Exception e) {
            System.out.println("转化IP信息异常");
        }
        System.out.println(cityInfo);
    }

}
